package com.xlab.xlabtestapp.slice;

import com.xlab.xlabtestapp.MainAbility;
import com.xlab.xlabtestapp.ResourceTable;
import com.xlab.xlabtestapp.provider.ContactItemViewHolder;
import com.xlab.xlabtestapp.provider.ContactProvider;
import com.xlab.xlabtestapp.utils.DeviceSelectDialog;
import com.xlab.xlabtestapp.utils.LogUtil;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.Operation;
import ohos.agp.components.*;
import ohos.data.distributed.common.*;
import ohos.data.distributed.user.SingleKvStore;
import ohos.sysappcomponents.contact.ContactAttributes;
import ohos.sysappcomponents.contact.ContactsCollection;
import ohos.sysappcomponents.contact.ContactsHelper;
import ohos.sysappcomponents.contact.entity.Contact;
import ohos.sysappcomponents.contact.entity.Name;

import java.util.ArrayList;
import java.util.List;

public class MainAbilitySlice extends AbilitySlice {
    private static final String TAG = MainAbilitySlice.class.getSimpleName();
    private static final String STORE_ID_KEY = "storeId";
    private static final String CONSTACTS_KEY = "contacts";
    private static final String IS_FORM_LOCAL_KEY = "isFormLocal";
    private static final String COLOR_INDEX_KEY = "colorIndex";
    private static final String SEPARATOR = "-";
    private static final String SEPARATOR_DATA = ";";

    private Button mSearchBtn;
    private ListContainer mListView;
    private ContactProvider<ContactItemViewHolder> mContactProvider;
    private final ArrayList<ContactItemViewHolder> mContactList = new ArrayList<>();
    private KvManager kvManager;
    private SingleKvStore singleKvStore;
    private static String storeId;
    private Text mTitle;
    private Image mTransform;
    private boolean isLocal;


    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_main);
        storeId = STORE_ID_KEY + System.currentTimeMillis();
        initUi();
        initView(intent);
        initDatabase();
        setEventListener();
    }

    private void initUi() {
        mSearchBtn = findComponentById(ResourceTable.Id_searchBttn);
        mListView = (ListContainer) this.findComponentById(ResourceTable.Id_listview);
        mContactProvider = new ContactProvider<>(this, mContactList);
        mListView.setItemProvider(mContactProvider);
    }

    private void setEventListener() {
        if (mSearchBtn != null) {
            mSearchBtn.setClickedListener(component -> {
                if (isLocal) {
                    readContacts();
                } else {
                    readRemoteContacts();
                }
                setListContact();
            });
        }
    }

    private void readRemoteContacts() {
        String remoteData = singleKvStore.getString(CONSTACTS_KEY);
        LogUtil.info(TAG, "remote data:" + remoteData);
        String[] datas = remoteData.split(SEPARATOR_DATA);
        for (String data : datas) {
            String[] params = data.split(SEPARATOR);
            mContactList.add(new ContactItemViewHolder(params[0], params[1], params[2]));
        }
    }

    private List<Contact> readContacts() {
        ContactsHelper contactsHelper = new ContactsHelper(getContext());
        ContactAttributes contactAttributes = new ContactAttributes();
        contactAttributes.add(ContactAttributes.Attribute.ATTR_NAME);
        contactAttributes.add(ContactAttributes.Attribute.ATTR_PHONE);
        ContactsCollection contactsCollection = contactsHelper.queryContacts(null, contactAttributes);
        Contact contact = contactsCollection.next();
        List<Contact> contacts = new ArrayList<>();
        StringBuilder datas = new StringBuilder();
        String device = KvManagerFactory.getInstance()
                .createKvManager(new KvManagerConfig(getContext()))
                .getLocalDeviceInfo().getName();
        while (contact != null) {
            contacts.add(contact);
            LogUtil.info(TAG, contact.getName().getFullName());
            String name = contact.getName().getFullName();
            String num = contact.getPhoneNumbers() == null ? "" : contact.getPhoneNumbers().get(0).getPhoneNumber();
            StringBuilder sb = new StringBuilder();
            sb.append(name).append(SEPARATOR).append(num).append(SEPARATOR).append(device);
            mContactList.add(new ContactItemViewHolder(name, num, device));
            contact = contactsCollection.next();
            datas.append(sb.toString()).append(SEPARATOR_DATA);
        }
        singleKvStore.putString(CONSTACTS_KEY, datas.toString());

        return contacts;
    }

    private void initDatabase() {
        // 创建分布式数据库管理对象
        KvManagerConfig config = new KvManagerConfig(this);
        kvManager = KvManagerFactory.getInstance().createKvManager(config);
        // 创建分布式数据库
        Options options = new Options();
        options.setCreateIfMissing(true).setEncrypt(false).setKvStoreType(KvStoreType.SINGLE_VERSION);
        singleKvStore = kvManager.getKvStore(options, storeId);
        // 订阅分布式数据变化
        KvStoreObserver kvStoreObserverClient = new KvStoreObserverClient();
        singleKvStore.subscribe(SubscribeType.SUBSCRIBE_TYPE_ALL, kvStoreObserverClient);
    }

    private class KvStoreObserverClient implements KvStoreObserver {
        @Override
        public void onChange(ChangeNotification notification) {
            String contacts = singleKvStore.getString(CONSTACTS_KEY);
            LogUtil.info(TAG, "data changed " + contacts);
        }
    }

    @Override
    public void onActive() {
        super.onActive();
    }

    @Override
    public void onForeground(Intent intent) {
        super.onForeground(intent);
    }

    private void setListContact() {
        mListView.setVisibility(Component.VISIBLE);
        mContactProvider.notifyDataChanged();
    }

    private void initView(Intent intent) {
        if (findComponentById(ResourceTable.Id_transform) instanceof Image) {
            mTransform = (Image) findComponentById(ResourceTable.Id_transform);
        }
        if (findComponentById(ResourceTable.Id_title) instanceof Text) {
            mTitle = (Text) findComponentById(ResourceTable.Id_title);
        }

        isLocal = !intent.getBooleanParam(IS_FORM_LOCAL_KEY, false);
        if (!isLocal) {
            storeId = intent.getStringParam(STORE_ID_KEY);
        }

        mTitle.setText(isLocal ? "本地端" : "远程端");
        mTransform.setVisibility(isLocal ? Component.VISIBLE : Component.INVISIBLE);
        mTransform.setClickedListener(component -> {
            DeviceSelectDialog dialog = new DeviceSelectDialog(MainAbilitySlice.this);
            dialog.setListener(deviceIds -> {
                if (deviceIds != null && !deviceIds.isEmpty()) {
                    // 启动远程页面
                    startRemoteFas(deviceIds);
                    // 同步远程数据库
                    singleKvStore.sync(deviceIds, SyncMode.PUSH_ONLY);
                }
                dialog.hide();
            });
            dialog.show();
        });
    }

    /**
     * Starting Multiple Remote Fas
     *
     * @param deviceIds deviceIds
     */
    private void startRemoteFas(List<String> deviceIds) {
        Intent[] intents = new Intent[deviceIds.size()];
        for (int i = 0; i < deviceIds.size(); i++) {
            Intent intent = new Intent();
            intent.setParam(IS_FORM_LOCAL_KEY, true);
            intent.setParam(COLOR_INDEX_KEY, i + 1);
            intent.setParam(STORE_ID_KEY, storeId);
            Operation operation = new Intent.OperationBuilder()
                    .withDeviceId(deviceIds.get(i))
                    .withBundleName(getBundleName())
                    .withAbilityName(MainAbility.class.getName())
                    .withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE)
                    .build();
            intent.setOperation(operation);
            intents[i] = intent;
        }
        startAbilities(intents);
    }

    @Override
    protected void onStop() {
        super.onStop();
        kvManager.closeKvStore(singleKvStore);
    }
}
